﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml.Serialization;

namespace Prototype
{
    public class People

    {
        private string Name { get; set; }
        public string ID { get; set; }
        public string Address { get; set; }
        public int Age { get; set; }

        public Foot LikeFoot { get; set; }

        public People()
        {

        }
        public People(string name)
        {
            this.Name = name;
        }
        public People Clone()
        {
            People people = new People(this.Name);
            people.ID = this.ID;
            people.Address = this.ID;
            people.Age = this.Age;
            return people;
        }
    }

    public class Foot
    {
        public string FootName { get; set; }
        public int GrowYears { get; set; }
    }

    public class CloneUtil
    {
        //利用反射实现深拷贝
        public static T DeepCopy<T>(T obj)
        {
            Type objType = obj.GetType();
            //1.判断T是否是值类型
            if (obj is string || objType.IsValueType)
            {
                return obj;
            }
            T result = default(T);
            object liveObj = Activator.CreateInstance(objType);  //对象要有无参构造函数
            //2.给新的实例字段赋值
            FieldInfo[] fields = objType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
            foreach (FieldInfo itemField in fields)
            {
                //3.这里有一个递归调用，下边的方法语句不能够拷贝，字段类型是其他引用类型的
                itemField.SetValue(liveObj, DeepCopy(itemField.GetValue(obj)));
                //itemField.SetValue(liveObj, itemField.GetValue(obj));
            }
            result = (T)liveObj;
            return result;
        }

        //利用xml序列化进行深拷贝
        public static T DeepCopyXml<T>(T obj)
        {
            T liveObj = default(T);
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializer xml = new XmlSerializer(obj.GetType());
                xml.Serialize(ms, obj);
                ms.Seek(0, SeekOrigin.Begin);
                liveObj = (T)xml.Deserialize(ms);
            }

            return liveObj;
        }

        //利用二进制序列化进行深拷贝
        public static T DeepCopyBin<T>(T obj)
        {
            T liveOjb = default(T);
            using (MemoryStream ms=new MemoryStream ())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, obj);
                ms.Seek(0, SeekOrigin.Begin);
                liveOjb = (T)bf.Deserialize(ms);
            }
            return liveOjb;
        }
    }
}
